#ifndef PHRESOURCE_H
#define PHRESOURCE_H

#include "PhResourceManager.h"

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

using namespace std;

namespace phoenix {

//! PhResource
/*!
	This class is provided for garbage collection of dynamically allocated
	objects. This can be used with phoenix::PhResourceManager to enable
	automatic garbage collection.
*/
class PhResource
	: public boost::enable_shared_from_this<PhResource>
{
protected:

	PhResourceManager< PhResource>* rmanager;

	PhResource( PhResourceManager<PhResource>* rm )
		:rmanager(rm)
	{
	}

public:

	virtual ~PhResource(){}

	//! Create
	/*!
		This is a sample create function that just returns a smart pointer to a
		new resource. It also adds the new resource to the given resource manager.
	*/
	template <typename T>
	static boost::shared_ptr<T> create( PhResourceManager<PhResource>* r )
	{
		boost::shared_ptr<T> newnode(new T(r));
		r->addResource( newnode->grab<PhResource>() );
		return newnode->grab<T>();
	}

	//! Grab
	/*!
		This should be used to grab a pointer to this resource.
		Derived classes should call grab<DerivedResource>().
	*/
	template <typename T>
	boost::shared_ptr<T> grab() { return boost::static_pointer_cast<T,PhResource>( shared_from_this() ); }

	virtual void drop()
	{
		rmanager->removeResource( this->grab<PhResource>() );
	}

};

typedef boost::shared_ptr<PhResource> PhResourcePointer;

}// namespace phoenix

#endif // PHRESOURCE_H
